package com.hiq.gogo;

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.util.Date;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 * This class is the main class of GoGo notifier.
 */
public class GoGoWindow extends JFrame implements ActionListener {

	private static final long serialVersionUID = 1L;

	private static final String PROPERTIES_FILE_NAME = "gogo.properties";
	private static final String FONT_SIZE_PROPERTY = "font-size";
	private static final String WIDTH_PROPERTY = "width";
	private static final String HEIGHT_PROPERTY = "height";
	private static final String BUTTON_MESSAGE_PROPERTY = "button_msg";
	private static final String START_MESSAGE = "Welcome to the GoGo Notifier!";

	private static final String RUNNING_MSG = "GoGo Notifier is running!";
	
	// in ms
	private static int PERIOD_TIME = 59 * 1000;

	/**
	 * Label with a message.
	 */
	private JLabel label;

	/**
	 * Properties file.
	 */
	private Properties p;

	/**
	 * Timer.
	 */
	private Timer timer;

	/**
	 * Shcedule.
	 */
	private Schedule schedule;

	/**
	 * A constructor.
	 */
	public GoGoWindow() {
		File propertiesFile = new File(PROPERTIES_FILE_NAME);
		try {
			if (propertiesFile.exists()) {
				p = Util.readProperties(propertiesFile);
			} else {
				p = defaultProperties();
			}
			schedule = Util.readShedule();
		} catch (IOException e) {
			Util.processException(e);
		}

		initAndShow();
		initTimer();
		initSystemTrayIcon();
	}

	/**
	 * Method makes the default properties.
	 * @return Properties class
	 * @throws IOException
	 */
	private Properties defaultProperties() throws IOException {
		Properties res = new Properties();
		res.setProperty(WIDTH_PROPERTY, "400");
		res.setProperty(BUTTON_MESSAGE_PROPERTY, "HIDE");
		res.setProperty(FONT_SIZE_PROPERTY, "24");
		res.store(new PrintWriter(PROPERTIES_FILE_NAME), null);
		return res;
	}

	private void initTimer() {
		timer = new Timer();
		timer.schedule(new TimerTask() {
			public void run() {
				String msg = schedule.getMessage(new Date()); 
				if (msg != null) {
					label.setText(msg);
					setVisible(true);
				}
			}
		}, PERIOD_TIME, PERIOD_TIME);
	}

	/**
	 * Initializing of the graphics and showing the form for the first time.
	 */
	private void initAndShow() {
		initForm();
		initLabel();
		initButton();
		setVisible(true);
	}

	private void initButton() {
		JButton button = new JButton();
		button.setText(this.p.getProperty(BUTTON_MESSAGE_PROPERTY));
		button.addActionListener(this);
		add(button, BorderLayout.SOUTH);
	}

	private void initLabel() {
		label = new JLabel(START_MESSAGE, JLabel.CENTER);
		Font f = new Font("Dialog", Font.PLAIN, getInt(FONT_SIZE_PROPERTY));
		label.setFont(f);
		add(label, BorderLayout.CENTER);
	}

	private void initForm() {
		setTitle("GoGo notifier");
		setSize(getInt(WIDTH_PROPERTY), getInt(HEIGHT_PROPERTY));
		setAlwaysOnTop(true);
		setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
		setLayout(new BorderLayout());

		Util.setFormAtTheCenter(this);
	}

	/**
	 * Getting an int property from the Properties object.
	 */
	private int getInt(String key) {
		return Integer.parseInt(this.p.getProperty(key));
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		this.setVisible(false);
	}
	
	private void initSystemTrayIcon(){
		final TrayIcon trayIcon;
		if (SystemTray.isSupported()) {
		    
			URL iconUrl = getClass().getClassLoader()
				.getResource("com/hiq/gogo/resources/tray.png");
		    
			SystemTray tray = SystemTray.getSystemTray();
		    Image image = Toolkit.getDefaultToolkit().getImage(iconUrl);
		    
		    ActionListener exitListener = new ActionListener() {
		        public void actionPerformed(ActionEvent e) {
		            System.exit(0);
		        }
		    };
		            
		    PopupMenu popup = new PopupMenu();
		    MenuItem defaultItem = new MenuItem("Exit");
		    defaultItem.addActionListener(exitListener);
		    popup.add(defaultItem);
		    
		    trayIcon = new TrayIcon(image, "GoGo notifier", popup);

		    ActionListener actionListener = new ActionListener() {
		        public void actionPerformed(ActionEvent e) {
		        	label.setText(RUNNING_MSG);
	                setVisible(true);
		        }
		    };
		    trayIcon.setImageAutoSize(true);
		    trayIcon.addActionListener(actionListener);

		    try {
		        tray.add(trayIcon);
		    } catch (AWTException e) {
		        System.err.println("TrayIcon could not be added.");
		    }

		} else {
		    //  System Tray is not supported
		}
	}

}